package Jasper.utils;

import org.omg.CORBA.PUBLIC_MEMBER;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author  jiangjiajia
 * @since JDK 1.8
 */
public class DBManager {
    //1.更新操作  包括insert update delete          --  返回值是 int 类型，操作数  可变参数
    public static Integer commonUpdate(String sql,Object ... obj){
        Connection connection = null;
        PreparedStatement ps = null;
        int rSet = 0;
        try {
            connection = DBUtils.getConnection();
            //开启事务
            connection.setAutoCommit(false);
            //预处理 sql 语句
            ps = connection.prepareStatement(sql);
            //给占位符赋值    传入参数的个数长度
            for (int i = 0;i <obj.length;i++){

                //
                ps.setObject(i+1,obj[i]);
            }
            //执行 sql 语句 返回结果集
            rSet = ps.executeUpdate();
            //提交事务
            connection.commit();
        } catch (SQLException e) {
            try {
                //回滚
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            DBUtils.closeAll(ps,connection);
        }
        return rSet;
    }
    //2.查询多个用户的数据  --  返回值是 List 类型，执行 sql 语句返回 Result对象， 多个用户对象

        //不能够写死，所有用T替代;                             反射用于创建对象
    public static <T> List<T> commonQuery(String sql,Class<T> clazz,Object ... obj){

        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rSet = null;
        List<T> list = new ArrayList<>();
        //不需要赋值，因为循环外面用不到这个T
        T t;
        try {
                //驱动和连接数据库
            connection = DBUtils.getConnection();
                //域占位
            ps = connection.prepareStatement(sql);
            //判断需不需要给占位符赋值  一个有参数值，一个没有参数值
            //  List<User> getList(int offset, int num);
            //  List<User> getList();
            if(obj != null){
                //给占位符进行赋值       User表的字段
                for (int i = 0;i < obj.length;i++){
                    //                         1， id
                    ps.setObject(i+1,obj[i]);
                }
            }
            //执行sql语句
            rSet = ps.executeQuery();
            //遍历结果集获取属性并封装成对象,再把对象存储到集合中
            while(rSet.next()){
                //1.创建实例对象    --  通过反射对象调用无参构造方法创建实例对象
                t = clazz.newInstance();
                //2.获取实体类的属性名，把属性名当做是字段名获取字段数据
                //获取所有属性对象
                Field[] fields = clazz.getDeclaredFields();
                for (Field field:fields) {
                    //打开访问权限
                    field.setAccessible(true);
                    //获取属性名
                    String name = field.getName();
                    //根据属性名获取字段数据
                    Object value = rSet.getObject(name);
                    //给实例对象的属性进行赋值
                    field.set(t,value);
                }
                //把实例对象添加到集合中
                list.add(t);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }finally {
            DBUtils.closeAll(rSet,ps,connection);
        }
        return list;
    }
    //3.查询个数            --  返回值是 int 类型，执行 sql 语句返回 Result对象，
    public static Integer commonCount(String sql,Object ... obj){
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rSet = null;
        int count = 0;
        try {
            connection = DBUtils.getConnection();
            connection.setAutoCommit(false);
            ps = connection.prepareStatement(sql);
            if(obj != null){
                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i+1,obj[i]);
                }
            }
            rSet = ps.executeQuery();
            if(rSet.next()){
                count = rSet.getInt(1);
            }
            connection.commit();
        } catch (SQLException e) {
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            DBUtils.closeAll(rSet,ps,connection);
        }
        return count;
    }
}
